﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using ServiceStack.Redis;
using BartonExtension;
using Cache.Model;
using Cache.Utils;

namespace Cache
{
    public class CacheManager
    {
        private string RedisDBConnectionString = ConfigurationExtensions.ValueOfConfig("cacheConnectionStr") == null ? "localhost:6379" : ConfigurationExtensions.ValueOfConfig("cacheConnectionStr");
        private PooledRedisClientManager clientManager;

        static CacheManager cacheObj;

        public static CacheManager instance { 
            get
            {
                if (cacheObj == null)
                {
                    cacheObj = new CacheManager();
                }
                return cacheObj;
            }
            set
            {
                instance = value;
            }
        }
        public CacheManager()
        {
            try
            {
                clientManager = new PooledRedisClientManager(new string[] { RedisDBConnectionString }, new string[] { RedisDBConnectionString }, new RedisClientManagerConfig()
                {
                    MaxReadPoolSize = 5,
                    MaxWritePoolSize = 5,
                    AutoStart = true
                });
            }
            catch (Exception ex)
            {
                clientManager = null;
            }
        }
        public CachingResult<T> doCacheObject<T>(T obj,string key)
        {
            try
            {
                CachingResult<T> result = new CachingResult<T>() { isSuccessCached = false };
                using(var client = clientManager.GetClient())
                {
                    result = client.CacheSet<T>(obj, key);
                }
                return result;
            }
            catch(Exception e)
            {
                return new CachingResult<T>() { isSuccessCached = false };
            }
        }
        public CachingResult<CacheObject> doCacheObject(CacheObject obj)
        {
            return doCacheObject<CacheObject>(obj, obj.cacheIdentifier);
        }
        public T objectFromCache<T>(string key)
        {
            T obj = default(T);
            using(var client = clientManager.GetClient())
            {
                obj = client.CacheGet<T>(key);
            }
            return obj;
        }
        public CachingResult<List<T>> doCacheItemsToPool<T>(List<T> items)
        {
            CachingResult<List<T>> result = new CachingResult<List<T>>();
            using (var client = clientManager.GetClient())
            {
                result = client.CacheItemsToPool<T>(items);
            }
            return result;
        }
        public List<T> GetItemsFromPool<T>()
        {
            List<T> list = null;
            using(var client = clientManager.GetClient())
            {
                list = client.GetItemsFromPool<T>();
            }
            return list;
        }
        public void CleanPool<T>()
        {
            using (var client = clientManager.GetClient())
            {
                client.CleanPool<T>();
            }
        }
        public bool DeleteItemFromPool<T>(T item)
        {
            bool result = false;
            using (var client = clientManager.GetClient())
            {
                result = client.DeleteItemFromPool<T>(item);
            }
            return result;
        }
        public bool RemoveCache(string key)
        {
            bool success = false;
            using(var client = clientManager.GetClient())
            {
                success = client.RemoveCache(key);
            }
            return success;
        }
    }
}
